home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d11 / frasrc14.arc / PROMPTS.C < prev    next >
C/C++ Source or Header  |  1990-08-02  |  67KB  |  2,427 lines

  1. /*
  2.     Various routines that prompt for things.
  3.     (Also, odds and ends that don't git anywhere else)
  4. */
  5.  
  6. #include <stdlib.h>
  7. #include <stdio.h>
  8. #include <string.h>
  9. #include <ctype.h>
  10. #include <dos.h>
  11. #include <time.h>
  12.  
  13. #include "fractint.h"
  14. #include "fractype.h"
  15.  
  16. extern double rqlim;
  17. extern char *strig[];
  18. extern char far inversionmessage[];        /* located in FARMSG.ASM */
  19. extern int bailout;
  20.  
  21. /* common strings - why keep several copies around? */
  22. char string001[] = {"  Use the cursor keys to select values to change"};
  23. char string002[] = {"  Type in any replacement values you wish to use"};
  24. char string003[] = {"Press the ENTER when finished (or ESCAPE to back out)"};
  25. char string004[] = {"...Press any key to continue.."};
  26.  
  27. struct fullscreenvalues
  28. {
  29.    char type;    /* 'd' or 's' */
  30.    union
  31.    {
  32.       double dval;
  33.       char   sval[16];
  34.    } uval;
  35. };
  36. char funnyglasses_map_name[80];
  37. extern char temp[], temp1[256];   /* temporary strings          */
  38. extern int mapset;
  39. extern int previewfactor;
  40. extern int xtrans, ytrans;
  41. extern int red_crop_left, red_crop_right;
  42. extern int blue_crop_left, blue_crop_right;
  43. extern int red_bright, blue_bright;
  44. extern char showbox; /* flag to show box and vector in preview */
  45. extern int debugflag;
  46. extern int whichimage;
  47. extern int xadjust;
  48. extern int eyeseparation;
  49. extern int glassestype;
  50. extern        findpath();
  51. FILE    *dacfile;
  52. char    MAP_name[80];
  53. extern        ValidateLuts();  /* read the palette file */
  54. int    mapset = 0;
  55. extern    int    overlay3d;        /* 3D overlay flag: 0 = OFF */
  56. extern    int    lookatmouse;
  57. extern    int full_color;
  58. extern    int haze;
  59. extern    int RANDOMIZE;
  60. extern    char light_name[];
  61. extern    int Ambient;
  62.  
  63. extern    int    initmode;    /* initial video mode        */
  64. extern    int    initfractype;    /* initial type set flag    */
  65. extern    int    initbatch;    /* 1 if batch run (no kbd)  */
  66. extern    int    init3d[20];    /* '3d=nn/nn/nn/...' values */
  67. extern    int    initcorners;        /* initial flag: corners set*/
  68. extern    double    initxmin,initxmax;    /* initial corner values    */
  69. extern    double    initymin,initymax;    /* initial corner values    */
  70. extern    double    initx3rd,inity3rd;    /* initial corner values    */
  71. extern    double    initparam[4];        /* initial parameters        */
  72. extern    int    display3d;    /* 3D display flag: 0 = OFF */
  73. extern    int    invert;     /* non-zero if inversion active */
  74. extern    double    inversion[3];    /* radius, xcenter, ycenter */
  75. extern    long    fudge;        /* 2**fudgefactor    */
  76. extern    int    bitshift;    /* fudgefactor        */
  77. extern    double    param[4];    /* up to four parameters    */
  78. extern    char    potfile[];    /* potential filename */
  79. extern    double    potparam[3];    /* three potential parameters*/
  80. extern    int    fractype;    /* if == 0, use Mandelbrot  */
  81. extern    char    floatflag;    /* floating-point fractals? */
  82. extern    int    maxit;        /* try this many iterations */
  83. extern    int    inside;     /* inside color */
  84. extern    int    outside;    /* outside color */
  85. extern    int    finattract;    /* finite attractor switch */
  86. extern    char    savename[80];    /* save files using this name */
  87. extern    char    ifsfilename[80];    /* IFS code file */
  88. extern    char    ifs3dfilename[80];  /* IFS 3D code file */
  89. extern    char    preview;    /* 3D preview mode flag */
  90. extern    int    decomp[];    /* decomposition parameters */
  91. extern    int    distest;    /* distance estimator option */
  92. extern    int    rflag, rseed;    /* Plasma-Cloud seed values */
  93. extern    int    fractype;    /* current fractal type */
  94. extern    int    transparent[];    /* transparency values */
  95. extern    int    numpasses;    /* 0 if single-pass, else 1 */
  96. extern    int    solidguessing;    /* 0 if disabled, else 1    */
  97. extern    int  boundarytraceflag; /* boundary trace option */
  98. extern    int    warn;        /* warn=yes flag */
  99. extern    int    soundflag;    /* sound option */
  100. extern    int    LogFlag;    /* non-zero if logarithmic palettes */
  101. extern    int    biomorph;    /* Biomorph flag */
  102. extern    unsigned char dacbox[256][3];     /* Video-DAC (filled in by SETVIDEO) */
  103. extern    unsigned char olddacbox[256][3]; /* backup copy of the Video-DAC */
  104. extern    long    xmin, xmax, ymin, ymax; /* screen corner values */
  105. extern    int    calc_status;    /* calc status: complete, resumable, ... */
  106. extern    int    xdots, ydots;    /* coordinates of dots on the screen  */
  107. extern    int    colors;     /* maximum colors available */
  108. extern    int    row, col;
  109.  
  110. /* Define command keys */
  111.  
  112. #define   PAGE_UP     1073
  113. #define   PAGE_DOWN     1081
  114. #define   LEFT_ARROW     1075
  115. #define   RIGHT_ARROW     1077
  116. #define   UP_ARROW     1072
  117. #define   DOWN_ARROW     1080
  118. #define   LEFT_ARROW_2     1115
  119. #define   RIGHT_ARROW_2  1116
  120. #define   UP_ARROW_2     1141
  121. #define   DOWN_ARROW_2     1145
  122. #define   HOME         1071
  123. #define   END         1079
  124. #define   ENTER      13
  125. #define   ENTER_2     1013
  126. #define   ESC         27
  127. #define   SPACE      32
  128. #define   F1         1059
  129. #define   F2         1060
  130. #define   F3         1061
  131. #define   F4         1062
  132. #define   F5         1063
  133. #define   F6         1064
  134. #define   F7         1065
  135. #define   F8         1066
  136. #define   F9         1067
  137. #define   F10         1068
  138.  
  139. /* --------------------------------------------------------------------- */
  140.  
  141. unsigned video_seg;           /* Current video display segment */
  142. int crtrows, crtcols;           /* Lines per page, columns/row */
  143. int isatextmode;           /* 1 if a text mode, 0 if graphics */
  144.  
  145. fullscreen_setup()        /* set up for full-screen prompting */
  146. {
  147.    int    video_mode;         /* current video mode */
  148.    unsigned char far *lowptr;     /* Low memory pointer */
  149.  
  150.    /* setup stuff for video */
  151. #ifdef __TURBOC__
  152.    lowptr = MK_FP(0, 0x449);        /* Set for low memory */
  153. #else
  154.    FP_SEG(lowptr) = 0;               /* Set for low memory */
  155.    FP_OFF(lowptr) = 0x449;           /* Get video mode */
  156. #endif
  157.    isatextmode = 1;               /* assume text */
  158.    if ((video_mode = *lowptr) >= 0 && video_mode < 4)
  159.       video_seg = 0xB800; /* Define video segment */
  160.    else if (video_mode == 7)           /* If monochrome */
  161.       video_seg = 0xB000;
  162.    else {                   /* graphics mode */
  163.       video_seg = 0xB800;           /* might be wrong, but not used */
  164.       isatextmode = 0;
  165.       }
  166.  
  167. #ifdef __TURBOC__
  168.    lowptr = MK_FP(0, 0x484);           /* get screen rows -1 */
  169. #else
  170.    FP_SEG(lowptr) = 0;
  171.    FP_OFF(lowptr) = 0x484;
  172. #endif
  173.    crtrows = (int)(*lowptr);
  174.  
  175. #ifdef __TURBOC__
  176.    lowptr = MK_FP(0, 0x44a);           /* get cols/row */
  177. #else
  178.    FP_SEG(lowptr) = 0;
  179.    FP_OFF(lowptr) = 0x44a;
  180. #endif
  181.    crtcols = (int)(*lowptr);
  182.  
  183.    if (video_mode == 7)
  184.    {
  185.       crtrows = 24; /* Since some mono adapters don't update lower RAM */
  186.       crtcols = 80;
  187.    }
  188.    /* end setup stuff for video */
  189. }
  190.  
  191. /* --------------------------------------------------------------------- */
  192.  
  193. fullscreen_prompt(        /* full-screen prompting routine */
  194.     int startrow,        /* start on this row */
  195.     int numprompts,     /* there are this many prompts (max) */
  196.     char * far *prompts,    /* array of prompting pointers */
  197.     double values[]     /* array of (initial) values */
  198.     )
  199. {
  200. char temp2[24][15];        /* string value of answers go here */
  201. int row, col, c, done, i, j, k;
  202.  
  203. if (numprompts <= 0)        /* ?? nothing to do! */
  204.     return(0);
  205.  
  206. fullscreen_setup();        /* set up for full-screen prompting */
  207.  
  208. movecursor(25,81);        /* kill cursor */
  209.  
  210. putstring(22,10,7,string001,0);
  211. putstring(23,10,7,string002,0);
  212. putstring(24,10,7,string003,0);
  213.  
  214. col = 0;
  215. for (i = 0; i < numprompts; i++) {    /* calculate initial display */
  216.     if (col < strlen(prompts[i]))
  217.         col = strlen(prompts[i]);
  218.     }
  219.  
  220. col+= 20;    /* answers start in this column */
  221. if (col > 65) col = 65;
  222.  
  223. for (i = 0; i < numprompts; i++) {    /* generate initial display */
  224.     sprintf(temp2[i], "%g", values[i]);
  225.     temp2[i][14] = 0;        /* safety first! */
  226.     putstring(startrow+i, 5, 7, prompts[i], 0);
  227.     putstring(startrow+i, col, 7, temp2[i], 0);
  228.     }
  229.  
  230. i = 0;
  231. k = 0;
  232. done = 0;
  233. while (!done) {
  234.     putstring(startrow+i, col-1, 112, "\032              \033", 0);
  235.     putstring(startrow+i, col, 112, temp2[i], 0);
  236.     while (! keypressed());
  237.     c = getakey();
  238.     putstring(startrow+i, col-1, 7,   "                ", 0);
  239.     putstring(startrow+i, col, 7,    temp2[i], 0);
  240.  
  241.     switch(c) {
  242.     case DOWN_ARROW:
  243.     case DOWN_ARROW_2:
  244.     case RIGHT_ARROW:
  245.     case RIGHT_ARROW_2:
  246.         k = 0;
  247.         if(i < numprompts-1)
  248.             i++;
  249.         else
  250.             i = 0;
  251.         break;
  252.     case UP_ARROW:
  253.     case UP_ARROW_2:
  254.     case LEFT_ARROW:
  255.     case LEFT_ARROW_2:
  256.         k = 0;
  257.         if(i > 0)
  258.             i--;
  259.         else
  260.             i = numprompts-1;
  261.         break;
  262.     case HOME:
  263.     case PAGE_UP:
  264.         k = 0;
  265.         i=0;
  266.         break;
  267.     case END:
  268.     case PAGE_DOWN:
  269.         k = 0;
  270.         i=numprompts-1;
  271.         break;
  272.     case ESC:
  273.         done = -1;
  274.         break;
  275.     case SPACE:
  276.     case F1:
  277.     case F2:
  278.     case F3:
  279.     case F4:
  280.     case F5:
  281.     case F6:
  282.     case F7:
  283.     case F8:
  284.     case F9:
  285.     case F10:
  286.     case ENTER:
  287.     case ENTER_2:
  288.         done = 1;
  289.         break;
  290.     default:
  291.         if ((c == '-' || c == '+' || c == '.' ||
  292.             (c >= '0' && c <= '9')) &&
  293.             k < 14) {
  294.             temp2[i][k++] = c;
  295.             temp2[i][k] = 0;
  296.             }
  297.         if ((c == 8 || c == 127 || c == 1083) && k > 0) {
  298.             k--;
  299.             temp2[i][k] = 0;
  300.             }
  301.         break;
  302.         }
  303.     }
  304.  
  305. if (done >= 0)
  306.     for (i = 0; i < numprompts; i++)    /* fill in the results */
  307.         values[i] = atof(temp2[i]);
  308.  
  309. return(done);
  310. }
  311.  
  312. fullscreen_prompt2(        /* full-screen prompting routine */
  313.     int startrow,        /* start on this row */
  314.     int numprompts,     /* there are this many prompts (max) */
  315.     char * far *prompts,    /* array of prompting pointers */
  316.     struct fullscreenvalues values[]        /* array of (initial) values */
  317.     )
  318. {
  319. char temp2[24][15];        /* string value of answers go here */
  320. int row, col, c, done, i, j, k;
  321.  
  322. if (numprompts <= 0)        /* ?? nothing to do! */
  323.     return(0);
  324.  
  325. fullscreen_setup();        /* set up for full-screen prompting */
  326.  
  327. movecursor(25,81);        /* kill cursor */
  328.  
  329. putstring(22,10,7,string001,0);
  330. putstring(23,10,7,string002,0);
  331. putstring(24,10,7,string003,0);
  332.  
  333. col = 0;
  334. for (i = 0; i < numprompts; i++)
  335. {    /* calculate initial display */
  336.     if(values[i].type == 'd')
  337.        sprintf(temp2[i], "%-10g", values[i].uval.dval);
  338.     else if(values[i].type == 's')
  339.        sprintf(temp2[i], "%-10s",  values[i].uval.sval);
  340.     else
  341.     {
  342.        /* this shouldn't happen */
  343.        if(debugflag)
  344.        {
  345.       movecursor(0,0);
  346.       printf(" %d %c\n",i,values[i].type);
  347.       getch();
  348.        }
  349.     }
  350.     if (col < strlen(prompts[i]))
  351.         col = strlen(prompts[i]);
  352. }
  353.  
  354. col+= 20;    /* answers start in this column */
  355. if (col > 65) col = 65;
  356.  
  357. for (i = 0; i < numprompts; i++) {    /* generate initial display */
  358.     putstring(startrow+i, 5, 7, prompts[i], 0);
  359.     putstring(startrow+i, col, 7, temp2[i], 0);
  360.     }
  361.  
  362. i = 0;
  363. k = 0;
  364. done = 0;
  365. while (!done) {
  366.     putstring(startrow+i, col-1, 112, "\032              \033", 0);
  367.     putstring(startrow+i, col, 112, temp2[i], 0);
  368.     while (! keypressed());
  369.     c = getakey();
  370.     putstring(startrow+i, col-1, 7,   "                ", 0);
  371.     putstring(startrow+i, col, 7,    temp2[i], 0);
  372.  
  373.     switch(c) {
  374.     case DOWN_ARROW:
  375.     case DOWN_ARROW_2:
  376.     case RIGHT_ARROW:
  377.     case RIGHT_ARROW_2:
  378.         k = 0;
  379.         if(i < numprompts-1)
  380.             i++;
  381.         else
  382.             i = 0;
  383.         break;
  384.     case UP_ARROW:
  385.     case UP_ARROW_2:
  386.     case LEFT_ARROW:
  387.     case LEFT_ARROW_2:
  388.         k = 0;
  389.         if(i > 0)
  390.             i--;
  391.         else
  392.             i = numprompts-1;
  393.         break;
  394.     case HOME:
  395.     case PAGE_UP:
  396.         k = 0;
  397.         i=0;
  398.         break;
  399.     case END:
  400.     case PAGE_DOWN:
  401.         k = 0;
  402.         i=numprompts-1;
  403.         break;
  404.     case ESC:
  405.         done = -1;
  406.         break;
  407.     case SPACE:
  408.     case F1:
  409.     case F2:
  410.     case F3:
  411.     case F4:
  412.     case F5:
  413.     case F6:
  414.     case F7:
  415.     case F8:
  416.     case F9:
  417.     case F10:
  418.     case ENTER:
  419.     case ENTER_2:
  420.         done = 1;
  421.         break;
  422.     default:
  423.     if(values[i].type=='d')
  424.     {
  425.        if ((c == '-' || c == '+' || c == '.' ||
  426.                (c >= '0' && c <= '9')) && k < 14)
  427.         {
  428.                temp2[i][k++] = c;
  429.                temp2[i][k] = 0;
  430.             }
  431.         else if ((c == 8 || c == 127 || c == 1083) && k > 0)
  432.         {
  433.                k--;
  434.                temp2[i][k] = 0;
  435.             }
  436.         }
  437.         else if( c >= 32 && c < 127)
  438.     {
  439.             temp2[i][k++] = c;
  440.             temp2[i][k] = 0;
  441.     }
  442.     else if ((c == 8 || c == 127 || c == 1083) && k > 0)
  443.     {
  444.         k--;
  445.             temp2[i][k] = 0;
  446.         }
  447.         break;
  448.     }
  449.     }
  450.     if (done >= 0)
  451.     for (i = 0; i < numprompts; i++)    /* fill in the results */
  452.     {
  453.        if(values[i].type == 'd')
  454.           values[i].uval.dval = atof(temp2[i]);
  455.        else if(values[i].type == 's')
  456.        strncpy(values[i].uval.sval,temp2[i],16);
  457.     }
  458. movecursor(0,0);
  459.  
  460. return(done);
  461. }
  462.  
  463. /* --------------------------------------------------------------------- */
  464.  
  465. /* prompt for and select choices */
  466. fullscreen_choice(int numchoices,      /* How many choices in list  */
  467.           char *choices[1],      /* array of choices           */
  468.           int numcols,          /* how many columns           */
  469.           int startrow,       /* upper left corner of list */
  470.           int startcol,       /* upper left corner of list */
  471.           int current)          /* start with this item      */
  472. {
  473.    char *s;
  474.    int done;
  475.    int colwidth;         /* width of a column */
  476.    int c;
  477.    int crow, ccol, i, j, k, k1;
  478.    int attribute;
  479.  
  480.    fullscreen_setup();            /* set up full-screen values */
  481.    colwidth = 22;          /* width of a column */
  482.    if(numcols == 1)
  483.       colwidth = 1;
  484.  
  485.  
  486.    numchoices--;
  487.  
  488.    /* display the list */
  489.    k = current;
  490.    for(i=0;i<=numchoices;i++)
  491.    {
  492.       ccol  = startcol + (i%numcols)*colwidth;
  493.       crow  = startrow + i/(numcols);
  494.       putstring(crow,ccol,7,choices[i],0);
  495.    }
  496.    movecursor(25,81); /* kill cursor */
  497.  
  498.    putstring(22,(crtcols-50)/2,7,
  499.       "Select one of the available choices above",
  500.       0);
  501.    putstring(23,(crtcols-66)/2,7,
  502.       "Use your cursor keypad, HOME, and END to move to your chosen item",
  503.       0);
  504.    putstring(24,(crtcols-66)/2,7,
  505.       "Press ENTER or the Space Bar when finished (or ESCAPE to back out)",
  506.       0);
  507.  
  508.    i = k;    /* start with current type highlighted */
  509.    ccol  = startcol + (i%numcols)*colwidth;
  510.    crow  = startrow + i/(numcols);
  511.    done = 0;
  512.    while(!done)
  513.    {
  514.       /* write type in reverse video */
  515.       putstring(crow,ccol-2,112,"\032\032", 0);
  516.       putstring(crow,ccol,112,choices[i],0);
  517.       while (! keypressed());
  518.       c = getakey();
  519.  
  520.       /* write type back to normal video */
  521.       putstring(crow,ccol-2,7,"  ", 0);
  522.       putstring(crow,ccol, 7,choices[i],0);
  523.  
  524.       switch(c)
  525.       {
  526.       case DOWN_ARROW:
  527.       case DOWN_ARROW_2:
  528.      i += numcols;
  529.      if(i > numchoices)
  530.         i = i%numcols;
  531.      break;
  532.       case UP_ARROW:
  533.       case UP_ARROW_2:
  534.      i -= numcols;
  535.      if(i < 0)
  536.         i = (numchoices/numcols)*numcols+i%numcols;
  537.      break;
  538.       case HOME:
  539.      i=0;
  540.      break;
  541.       case END:
  542.      i=numchoices;
  543.      break;
  544.       case RIGHT_ARROW:
  545.       case RIGHT_ARROW_2:
  546.      i ++;
  547.      if(i > numchoices)
  548.         i = 0;
  549.      break;
  550.       case LEFT_ARROW:
  551.       case LEFT_ARROW_2:
  552.      i --;
  553.      if(i < 0)
  554.         i = numchoices;
  555.      break;
  556.       case ENTER:
  557.       case ENTER_2:
  558.       case SPACE:
  559.       case F1:
  560.       case F2:
  561.       case F3:
  562.       case F4:
  563.       case F5:
  564.       case F6:
  565.       case F7:
  566.       case F8:
  567.       case F9:
  568.       case F10:
  569.      done = 1;
  570.      break;
  571.       case ESC:
  572.      done = -1;
  573.      break;
  574.       default:
  575.      continue;
  576.       }
  577.       ccol = startcol + (i%numcols)*colwidth;
  578.       crow = startrow + i/(numcols);
  579.    }
  580.    setclear();
  581.    if (done < 0)
  582.       return(done);
  583.    else
  584.       return(i);
  585. }
  586.  
  587. /* --------------------------------------------------------------------- */
  588.  
  589. /* compare for sort of type table */
  590. compare(const void *i, const void *j)
  591. {
  592.    return(strcmp(fractalspecific[(int)*((unsigned char*)i)].name,
  593.            fractalspecific[(int)*((unsigned char*)j)].name));
  594. }
  595.  
  596. /* --------------------------------------------------------------------- */
  597.  
  598. clear_line(int row, int start, int stop, int color) /* clear part of a line */
  599. {
  600.    int col;
  601.    for(col=start;col<= stop;col++)
  602.       putstring(row,col,color," ",0);
  603. }
  604.  
  605. /* --------------------------------------------------------------------- */
  606. get_fracttype(int t)        /* prompt for and select fractal type */
  607. {
  608.    char *speed_pt;
  609.    int speed_col;
  610.    char tname[40];        /* target name for speed key */
  611.    int cct;            /* which character for speed key */
  612.    char *s;
  613.    int oldhelpmode;
  614.    int done;
  615.    int numtypes;         /* length of list    */
  616.    int numcols;          /* number of columns */
  617.    int colwidth;         /* width of a column */
  618.    int startrow, startcol;     /* upper left corner of list */
  619.    int c;
  620.    int crow, ccol, i, j, k, k1;
  621.    int attribute;
  622.  
  623.    unsigned char onthelist[256];    /* list of REAL name locations */
  624.  
  625. restart:
  626.    lookatmouse = 2; /* don't need to save/restore old value, main will reset */
  627.    speed_col = 15;  /* column to start speed key prompt */
  628.    speed_pt = "Speed key string ->";
  629.    *tname = cct = 0;
  630.    setvideomode(3,0,0,0);        /* switch to text mode */
  631.  
  632.    fullscreen_setup();            /* set up full-screen values */
  633.  
  634.    /* setup context sensitive help */
  635.    oldhelpmode = helpmode;
  636.    helpmode = HELPFRACTALS;
  637.  
  638.    /* set up details of how type list is displayed on the screen */
  639.    numcols  =  5;          /* number of columns */
  640.    colwidth = 16;          /* width of a column */
  641.    startrow =  5;          /* upper left corner of list */
  642.    startcol =  1;          /* upper left corner of list */
  643.  
  644.    i = -1;
  645.    j = -1;
  646.    k = 0;
  647.    while(fractalspecific[++i].name)
  648.    {
  649.       if (fractalspecific[i].name[0] == '*')
  650.      continue;
  651.       onthelist[++j] = i;    /* remember where the real item is */
  652.       if (strcmp(fractalspecific[onthelist[j]].name,
  653.          fractalspecific[t].name) == 0 ||
  654.       (fractalspecific[t].name[0] == '*' &&
  655.       strcmp(fractalspecific[onthelist[j]].name,
  656.          fractalspecific[fractalspecific[t].tofloat].name) == 0))
  657.       k = j;
  658.    }
  659.    k1 = onthelist[k]; /* remember index of current type */
  660.    numtypes = j;
  661.    onthelist[numtypes+1] = 0;    /* allow index to overshoot harmlessly */
  662.    qsort(onthelist,1+numtypes,1,compare); /* sort type list */
  663.  
  664.    putstring(2,(crtcols-50)/2,7,
  665.       "Select one of the available fractal types below",
  666.       0);
  667.  
  668.    /* display the list */
  669.    for(i=0;i<=numtypes;i++)
  670.    {
  671.       if(onthelist[i] == k1)
  672.      k = i;  /* this is the current type */
  673.       ccol  = startcol + (i%numcols)*colwidth;
  674.       crow  = startrow + i/(numcols);
  675.       putstring(crow,ccol,7,fractalspecific[onthelist[i]].name,0);
  676.    }
  677.    movecursor(25,81); /* kill cursor */
  678.  
  679.    putstring(22,(crtcols-66)/2,7,
  680.       "Use your cursor keypad, HOME, and END to move to your chosen item",
  681.       0);
  682.    putstring(23,(crtcols-66)/2,7,
  683.       "(or press the F1 key for a short description of each fractal type)",
  684.       0);
  685.    putstring(24,(crtcols-66)/2,7,
  686.       "Press <ENTER> to select or <ESC> to return to the previous screen",
  687.       0);
  688.  
  689.    i = k;    /* start with current type highlighted */
  690.    ccol  = startcol + (i%numcols)*colwidth;
  691.    crow  = startrow + i/(numcols);
  692.    done = 0;
  693.    while(!done)
  694.    {
  695.       /* write type in reverse video */
  696.       putstring(crow,ccol,112,fractalspecific[onthelist[i]].name,0);
  697.  
  698.       while (! keypressed()); /* wait for a keystroke */
  699.       c = getakey();
  700.  
  701.       /* write type back to normal video */
  702.       putstring(crow,ccol, 7,fractalspecific[onthelist[i]].name,0);
  703.  
  704.       /* speed key case */
  705.       if( (33 <= c && c <= 126) || (c==8 && cct) )
  706.       {
  707.      int match;
  708.      c = tolower(c);
  709.      if(c==8) /* backspace */
  710.      {
  711.         putstring(21,speed_col+strlen(speed_pt)+ --cct,7," ",0);
  712.         tname[cct] = 0;
  713.         if(cct == 0) /* backspaced out of speed mode */
  714.            clear_line(21,speed_col,crtcols-1,7);
  715.      }
  716.      else
  717.      {
  718.         if(cct<39) /* add char to speed key buffer */
  719.         {
  720.            tname[cct] = c;
  721.            tname[++cct] = 0;
  722.         }
  723.      }
  724.  
  725.      /* write speed key buffer monitor window */
  726.      putstring(21,speed_col,7,speed_pt,0);
  727.      putstring(21,speed_col+strlen(speed_pt),112,tname,0);
  728.  
  729.      /* locate matching type */
  730.      i = 0; /* start at top of list */
  731.      while(i <= numtypes &&
  732.          (match=strncmp(tname,fractalspecific[onthelist[i]].name,cct))>0)
  733.         i++;
  734.      if(match < 0 && i > 0)  /* oops - overshot    */
  735.         i--;
  736.      else if(i > numtypes) /* bumped end of list */
  737.         i = numtypes;
  738.       }
  739.       else
  740.       {
  741.      if(c==27 && cct)
  742.         c = 0; /* exit speed key mode */
  743.      *tname = cct = 0;
  744.      clear_line(21,speed_col,crtcols-1,7); /* zap speed key window */
  745.       }
  746.       switch(c)
  747.       {
  748.       case DOWN_ARROW:
  749.       case DOWN_ARROW_2:
  750.      i += numcols;
  751.      if(i > numtypes)
  752.         i = i%numcols;
  753.      break;
  754.       case UP_ARROW:
  755.       case UP_ARROW_2:
  756.      i -= numcols;
  757.      if(i < 0)
  758.         i = (numtypes/numcols)*numcols+i%numcols;
  759.      break;
  760.       case HOME:
  761.      i=0;
  762.      break;
  763.       case END:
  764.      i=numtypes;
  765.      break;
  766.       case RIGHT_ARROW:
  767.       case RIGHT_ARROW_2:
  768.      i ++;
  769.      if(i > numtypes)
  770.         i = 0;
  771.      break;
  772.       case LEFT_ARROW:
  773.       case LEFT_ARROW_2:
  774.      i --;
  775.      if(i < 0)
  776.         i = numtypes;
  777.      break;
  778.       case ENTER:
  779.       case ENTER_2:
  780.       case SPACE:
  781.       case F1:
  782.       case F2:
  783.       case F3:
  784.       case F4:
  785.       case F5:
  786.       case F6:
  787.       case F7:
  788.       case F8:
  789.       case F9:
  790.       case F10:
  791.      done = 1;
  792.      break;
  793.       case ESC:
  794.      done = -1;
  795.      break;
  796.       default:
  797.      break;
  798.       }
  799.       /* calculate position of type on screen */
  800.       ccol = startcol + (i%numcols)*colwidth;
  801.       crow = startrow + i/(numcols);
  802.    }
  803.    clscr();
  804.    helpmode = oldhelpmode;
  805.    if (done >= 0) {
  806.       if (get_fract_params(onthelist[i], t) < 0)
  807.     goto restart;
  808.       return(onthelist[i]);
  809.       }
  810.    return(-1);
  811. }
  812.  
  813. /* --------------------------------------------------------------------- */
  814.  
  815. get_fract_params(        /* prompt for fractal parameters */
  816.     int newfractype,    /* new fractal type */
  817.     int oldfractype     /* previous fractal type */
  818.     )
  819. {
  820. int numparams,numtrig;
  821. int i;
  822. struct fullscreenvalues paramvalues[10];
  823. char *choices[10];
  824. int oldbailout;
  825. int promptnum;
  826.  
  827. static char *trg[] = {"First Function","Second Function",
  828.               "Third Function","Fourth Function"};
  829.  
  830. initfractype = newfractype;
  831.  
  832. if (strcmp(fractalspecific[initfractype].param[3],
  833.     "Imaginary portion of p2") == 0)
  834.     if (get_formula_name() < 0)    /* scan for the formula name */
  835.         return(-1);
  836.  
  837.  for ( i = 0; i < 4; i++)
  838.  {
  839.      initparam[i] = fractalspecific[initfractype].paramvalue[i];
  840.      paramvalues[i].type = 'd';
  841.      paramvalues[i].uval.dval = initparam[i];
  842.  }
  843. for (numparams = 0; numparams < 4; numparams++) {
  844.     if (fractalspecific[initfractype].param[numparams][0] == 0) break;
  845.     choices[numparams] = fractalspecific[initfractype].param[numparams];
  846.     if (numparams == 0) {
  847.         printf("\n\n Select your options for fractal type %s",
  848.             fractalspecific[initfractype].name[0] != '*' ?
  849.             fractalspecific[initfractype].name         :
  850.             &fractalspecific[initfractype].name[1]         );
  851.         printf("\n\n Please enter any parameters that apply \n\n");
  852.         }
  853.     }
  854.  numtrig = get_trig_num(fractalspecific[initfractype].flags);
  855.  
  856.   for(i=0; i<numtrig; i++)
  857.   {
  858.     paramvalues[i+numparams].type = 's';
  859.     strcpy(paramvalues[i+numparams].uval.sval,trigfn[trigndx[i]].name);
  860.     choices[i+numparams] = trg[i];
  861.   }
  862.   if(fabs(potparam[2]) == 0.0 && (decomp[0] <= 0 || decomp[1] <= 0)
  863.    && fractalspecific[initfractype].orbit_bailout)
  864.   {
  865.      promptnum = numparams+numtrig+1;
  866.      choices[numparams+numtrig] = "Bailout value (0 means use default)";
  867.      paramvalues[numparams+numtrig].type = 'd';
  868.      paramvalues[numparams+numtrig].uval.dval = oldbailout = bailout;
  869.   }
  870.   else    /* under these conditions bailout is ignored, so why ask for it? */
  871.      promptnum = numparams+numtrig;
  872.  if (fullscreen_prompt2(10,promptnum,choices, paramvalues) < 0)
  873.          return(-1);
  874.  for ( i = 0; i < numparams; i++)
  875.      initparam[i] = paramvalues[i].uval.dval;
  876.  for ( i = 0; i < numtrig; i++)
  877.  {
  878.     paramvalues[i+numparams].uval.sval[4] = 0;
  879.     if(paramvalues[i+numparams].uval.sval[3]==32)
  880.     paramvalues[i+numparams].uval.sval[3] = 0;
  881.     set_trig_array(i, paramvalues[i+numparams].uval.sval);
  882.  }
  883.  
  884.   if(fabs(potparam[2]) == 0.0 && (decomp[0] <= 0 || decomp[1] <= 0)
  885.    && fractalspecific[initfractype].orbit_bailout)
  886.   {
  887.      bailout = paramvalues[numparams+numtrig].uval.dval;
  888.  
  889.      if (bailout != 0 && (bailout < 4 || bailout > 32000))
  890.     bailout = oldbailout;
  891.   }
  892.  
  893.  if (newfractype != oldfractype) {
  894.      invert = 0;
  895.      inversion[0] = inversion[1] = inversion[2] = 0;
  896.      for ( i = 0; i < 3; i++)
  897.          potparam[i] = 0.0;
  898.      };
  899.  
  900. initcorners = 1;
  901. initxmin = fractalspecific[initfractype].xmin;
  902. initxmax = fractalspecific[initfractype].xmax;
  903. initymin = fractalspecific[initfractype].ymin;
  904. initymax = fractalspecific[initfractype].ymax;
  905. initx3rd = initxmin;
  906. inity3rd = initymin;
  907. for ( i = 0; i < 4; i++)
  908.    fractalspecific[newfractype].paramvalue[i] = initparam[i];
  909.  
  910. return(0);
  911.  
  912. }
  913.  
  914. /* --------------------------------------------------------------------- */
  915.  
  916. /*
  917.   Read a formula file, picking off the formula names.
  918.   Formulas use the format "  name = { ... }  name = { ... } "
  919. */
  920.  
  921. extern char FormFileName[];    /* file to find the formulas in */
  922. extern char FormName[];     /* Name of the Formula (if not null) */
  923.  
  924. get_formula_name()    /* get the fractal formula name */
  925. {
  926.    int numcols;          /* number of columns */
  927.    int startrow, startcol;     /* upper left corner of list */
  928.    char *choices[41], choicetext[41][21];
  929.    char fullfilename[200];    /* Full file name */
  930.    int numformulas, i;
  931.    FILE *File;
  932.  
  933.    FormName[0] = 0;        /* start by declaring failure */
  934.    for (i = 0; i < 41; i++) {
  935.       choicetext[i][0] = 0;
  936.       choices[i] = choicetext[i];
  937.       }
  938.  
  939.    setclear();
  940.    printf("\n\n Enter the name of your Formula File (if not %s) .. ",
  941.       FormFileName);
  942.    gets(temp1);
  943.    if (temp1[0] != 0) strcpy(FormFileName, temp1);
  944.       if (strchr(FormFileName,'.') == NULL)
  945.      strcat(FormFileName,".frm");
  946.  
  947.    findpath(FormFileName, fullfilename);    /* BDT get full path name */
  948.  
  949.    if((File = fopen(fullfilename, "rt")) == NULL) {
  950.      buzzer(2);
  951.      printf("\n?? I Can't find %s\n", FormFileName);
  952.      printf("\n\n%s",string004);
  953.      getakey();
  954.      return(-1);
  955.    }
  956.  
  957.    numformulas = 0;
  958.    while(fscanf(File, " %20[^ \n\t({]", choices[numformulas]) != EOF) {
  959.       int c;
  960.  
  961.       while(c = getc(File)) {
  962.      if(c == EOF || c == '{' || c == '\n')
  963.         break;
  964.       }
  965.       if(c == EOF)
  966.      break;
  967.       else if(c != '\n'){
  968.      numformulas++;
  969.      if (numformulas >= 41-1) break;
  970. skipcomments:
  971.      if(fscanf(File, "%200[^}]", fullfilename) == EOF) break;
  972.      if (getc(File) != '}') goto skipcomments;
  973.      if (stricmp(choices[numformulas-1],"") == 0 ||
  974.          stricmp(choices[numformulas-1],"comment") == 0)
  975.          numformulas--;
  976.       }
  977.    }
  978.    fclose(File);
  979.  
  980.    /* set up details of how type list is displayed on the screen */
  981.    numcols  =  3;          /* number of columns */
  982.    startrow =  5;          /* upper left corner of list */
  983.    startcol = 10;          /* upper left corner of list */
  984.  
  985.    if ((i = fullscreen_choice(numformulas, choices,numcols,startrow,startcol,0)) >= 0)
  986.       strcpy(FormName, choices[i]);
  987.  
  988.    if (RunForm(FormName)) {
  989.        FormName[0] = 0;     /* declare failure */
  990.        buzzer(2);
  991.        printf("\n\n%s",string004);
  992.        getakey();
  993.        return(-1);
  994.        }
  995.  
  996. return(0);
  997. }
  998.  
  999. /* --------------------------------------------------------------------- */
  1000.  
  1001. get_decomp_params()        /* prompt for decomposition parameters */
  1002. {
  1003. static char *decomp_prompts[] = {
  1004.    "Number of Colors  (0 for no decomposition)",
  1005.    "New Bailout Value (0 for default value)",
  1006.    ""
  1007.    };
  1008. double values[2];
  1009.  
  1010.     memcpy(olddacbox,dacbox,256*3);       /* save the DAC */
  1011.     setvideomode(3,0,0,0);           /* clear the screen entirely */
  1012.     memcpy(dacbox,olddacbox,256*3);       /* restore the DAC */
  1013.  
  1014.    values[0] = decomp[0];
  1015.    values[1] = 0;
  1016.    printf("\n\nPlease enter your Decomposition Parameters:\n");
  1017.    if (fullscreen_prompt(10,2,decomp_prompts,values) < 0)
  1018.       return(-1);
  1019.    decomp[0] = values[0];
  1020.    decomp[1] = values[1];
  1021.    return(0);
  1022. }
  1023.  
  1024. /* --------------------------------------------------------------------- */
  1025.  
  1026. get_invert_params()        /* prompt for inversion parameters */
  1027. {
  1028. extern int StandardFractal();
  1029. extern int calcmand();
  1030. static char *invert_prompts[] = {
  1031.    "Radius of inversion or \"auto\")",
  1032.    "X Center inversion  or \"auto\"",
  1033.    "Y Center inversion  or \"auto\"",
  1034.    ""
  1035.    };
  1036. struct fullscreenvalues values[4];
  1037. int i;
  1038.    if(fractalspecific[initfractype].calctype != StandardFractal &&
  1039.       fractalspecific[initfractype].calctype != calcmand)
  1040.       return(0);
  1041.  
  1042.     memcpy(olddacbox,dacbox,256*3);       /* save the DAC */
  1043.     setvideomode(3,0,0,0);           /* clear the screen entirely */
  1044.     memcpy(dacbox,olddacbox,256*3);       /* restore the DAC */
  1045.  
  1046.    helpmessage(inversionmessage);
  1047.  
  1048.    for(i=0;i<3;i++)
  1049.    {
  1050.        values[i].type = 's';
  1051.        if(inversion[i] == AUTOINVERT)
  1052.       sprintf(values[i].uval.sval,"auto");
  1053.        else
  1054.       sprintf(values[i].uval.sval,"%g",inversion[i]);
  1055.    }
  1056.    if (fullscreen_prompt2(10,3,invert_prompts,values) < 0)
  1057.       return(-1);
  1058.    for(i=0;i<3;i++)
  1059.       if(values[i].uval.sval[0] == 'a' || values[i].uval.sval[0] == 'A')
  1060.      inversion[i] = AUTOINVERT;
  1061.       else
  1062.      inversion[i] = atof(values[i].uval.sval);
  1063.    invert = 3;
  1064.    return(0);
  1065. }
  1066.  
  1067. /* --------------------------------------------------------------------- */
  1068.  
  1069. get_ifs3d_params()        /* prompt for 3D IFS parameters */
  1070. {
  1071.    char *s;
  1072. int k;
  1073. static char *ifs3d_prompts[] = {
  1074.    "X-axis rotation in degrees",
  1075.    "Y-axis rotation in degrees",
  1076.    "Z-axis rotation in degrees",
  1077.    "Perspective distance [1 - 999, 0 for no persp]",
  1078.    "X shift with perspective (positive = right)",
  1079.    "Y shift with perspective (positive = up   )",
  1080.    "Stereo (R/B 3D)? (0=no,1=alternate,2=superimpose,3=photo)",
  1081.    ""
  1082.    };
  1083.    double values[sizeof(ifs3d_prompts)/sizeof(char *)];
  1084.  
  1085.     fullscreen_setup();
  1086.     memcpy(olddacbox,dacbox,256*3);       /* save the DAC */
  1087.     setvideomode(3,0,0,0);           /* clear the screen entirely */
  1088.     memcpy(dacbox,olddacbox,256*3);       /* restore the DAC */
  1089.  
  1090.    k = 0;
  1091.    values[k++] = XROT;
  1092.    values[k++] = YROT;
  1093.    values[k++] = ZROT;
  1094.    values[k++] = ZVIEWER;
  1095.    values[k++] = XSHIFT;
  1096.    values[k++] = YSHIFT;
  1097.    values[k++] = glassestype;
  1098.    s = "3D Parameters";
  1099.       putstring(0,(crtcols-strlen(s))/2,7,s,0);
  1100.  
  1101.    if (fullscreen_prompt(3,k,ifs3d_prompts,values) < 0)
  1102.       return(-1);
  1103.    k = 0;
  1104.    XROT    =  values[k++];
  1105.    YROT    =  values[k++];
  1106.    ZROT    =  values[k++];
  1107.    ZVIEWER =  values[k++];
  1108.    XSHIFT  =  values[k++];
  1109.    YSHIFT  =  values[k++];
  1110.    glassestype = values[k++];
  1111.    if(glassestype)
  1112.    {
  1113.       if(get_funny_glasses_params())
  1114.      return(-1);
  1115.       check_mapfile();
  1116.    }
  1117.    return(0);
  1118. }
  1119.  
  1120. /* --------------------------------------------------------------------- */
  1121.  
  1122. get_3d_params()     /* prompt for 3D parameters */
  1123. {
  1124.    int numcols;         /* number of columns */
  1125.    int startrow;        /* upper left corner of list */
  1126.    int startcol;        /* upper left corner of list */
  1127.    char *choices[8];
  1128.    char c;
  1129.    int numprompts;
  1130.    int sphere,filltype;
  1131.    char *s;
  1132.  
  1133.    char *prompts3d[25];
  1134.    double values[25];
  1135.  
  1136.    struct fullscreenvalues uvalues[25];
  1137.    int i, j, k;
  1138.  
  1139.    if (initmode < 0 || !display3d || initbatch)
  1140.       return(0);
  1141.  
  1142. restart_1:
  1143.  
  1144.    fullscreen_setup(); /* just to get value of crtcols */
  1145.    setclear();
  1146.  
  1147.    s = "3D Mode Selection";
  1148.    putstring(0,(crtcols-strlen(s))/2,7,s,0);
  1149.  
  1150.    k=-1;
  1151.  
  1152.    prompts3d[++k]= "Preview Mode?                        (yes or no)";
  1153.    uvalues[k].type = 's';
  1154.    if(preview)
  1155.       strcpy(uvalues[k].uval.sval,"yes");
  1156.    else
  1157.       strcpy(uvalues[k].uval.sval,"no");
  1158.  
  1159.    prompts3d[++k]= "    Show Box?                        (yes or no)";
  1160.    uvalues[k].type = 's';
  1161.    if(showbox)
  1162.       strcpy(uvalues[k].uval.sval,"yes");
  1163.    else
  1164.       strcpy(uvalues[k].uval.sval,"no");
  1165.  
  1166.    prompts3d[++k]= "Coarseness, preview/grid (in y dir)";
  1167.    uvalues[k].type = 'd';
  1168.    uvalues[k].uval.dval = previewfactor;
  1169.  
  1170.    prompts3d[++k]= "Spherical Projection?                (yes or no)";
  1171.    uvalues[k].type = 's';
  1172.    if(sphere = SPHERE)
  1173.       strcpy(uvalues[k].uval.sval,"yes");
  1174.    else
  1175.       strcpy(uvalues[k].uval.sval,"no");
  1176.  
  1177.    prompts3d[++k]= "Stereo (R/B 3D)? (0=no,1=alternate,2=superimpose,3=photo)";
  1178.    uvalues[k].type = 'd';
  1179.    uvalues[k].uval.dval = glassestype;
  1180.  
  1181.    prompts3d[++k]= "";
  1182.  
  1183.    if (fullscreen_prompt2(3,k,prompts3d,uvalues) < 0)
  1184.       return(-1);
  1185.  
  1186.    k=0;
  1187.  
  1188.    if((c = *(uvalues[k++].uval.sval))=='y' || c == 'Y')
  1189.       preview = 1;
  1190.    else
  1191.       preview = 0;
  1192.  
  1193.    if((c = *(uvalues[k++].uval.sval))=='y' || c == 'Y')
  1194.       showbox = 1;
  1195.    else
  1196.       showbox = 0;
  1197.  
  1198.    previewfactor  = uvalues[k++].uval.dval;
  1199.  
  1200.    if((c = *(uvalues[k++].uval.sval))=='y' || c == 'Y')
  1201.       sphere = 1;
  1202.    else
  1203.       sphere = 0;
  1204.  
  1205.    glassestype = uvalues[k++].uval.dval;
  1206.  
  1207.    /* check ranges */
  1208.    if(preview)
  1209.       preview = 1;
  1210.    else
  1211.       preview = 0;
  1212.  
  1213.    if(previewfactor < 8)
  1214.       previewfactor = 8;
  1215.    else if(previewfactor > 128)
  1216.       previewfactor = 128;
  1217.  
  1218.    if(sphere && !SPHERE)
  1219.    {
  1220.       SPHERE = TRUE;
  1221.       set_3d_defaults();
  1222.    }
  1223.    else if(!sphere && SPHERE)
  1224.    {
  1225.       SPHERE = FALSE;
  1226.       set_3d_defaults();
  1227.    }
  1228.  
  1229.    if(glassestype < 0)
  1230.       glassestype = 0;
  1231.    else if(glassestype > 3)
  1232.       glassestype = 3;
  1233.    if(glassestype)
  1234.       whichimage = 1;
  1235.  
  1236.    k=0;
  1237.    choices[k++] = "make a surface grid";
  1238.    choices[k++] = "just draw the points";
  1239.    choices[k++] = "connect the dots (wire frame)";
  1240.    choices[k++] = "surface fill (colors interpolated)";
  1241.    choices[k++] = "surface fill (colors not interpolated)";
  1242.    choices[k++] = "solid fill (bars up from \"ground\")";
  1243.    if(SPHERE)
  1244.       choices[k++] = "light source";
  1245.    else
  1246.    {
  1247.       choices[k++] = "light source before transformation";
  1248.       choices[k++] = "light source after transformation";
  1249.    }
  1250.    numcols  =  1;          /* number of columns */
  1251.    startrow = 12;          /* upper left corner of list */
  1252.    startcol = 23;          /* upper left corner of list */
  1253.  
  1254.    s = "Select Fill Type";
  1255.    putstring(startrow-2,(crtcols-strlen(s))/2,7,s,0);
  1256.    clear_line(22,10,60,7);
  1257.    clear_line(23,10,60,7);
  1258.    clear_line(24,10,60,7);
  1259.  
  1260.    i = FILLTYPE+1;
  1261.  
  1262.    if ((i = fullscreen_choice(k, choices,numcols,startrow,startcol,i)) >= 0)
  1263.       FILLTYPE = i-1;
  1264.    else goto restart_1;
  1265.  
  1266.    if(glassestype)
  1267.    {
  1268.       if(get_funny_glasses_params())
  1269.      goto restart_1;
  1270.    }
  1271.  
  1272.    check_mapfile();
  1273.  
  1274. restart_3:
  1275.  
  1276.    setclear();
  1277.  
  1278.    if(SPHERE)
  1279.    {
  1280.       s = "Sphere 3D Parameters";
  1281.       putstring(0,(crtcols-strlen(s))/2,7,s,0);
  1282.       s = "Sphere is on its side; North pole to right";
  1283.       putstring(1,(crtcols-strlen(s))/2,7,s,0);
  1284.       s = "180 deg long. is top; 0 deg bottom;-90 deg lat. is left; 90 deg. is right";
  1285.       putstring(2,(crtcols-strlen(s))/2,7,s,0);
  1286.  
  1287.       prompts3d[0] = "Longitude start (degrees)";
  1288.       prompts3d[1] = "Longitude stop  (degrees)";
  1289.       prompts3d[2] = "Latitude start  (degrees)";
  1290.       prompts3d[3] = "Latitude stop   (degrees)";
  1291.       prompts3d[4] = "Radius scaling factor in pct";
  1292.  
  1293.    }
  1294.    else
  1295.    {
  1296.       s = "Planar 3D Parameters";
  1297.       putstring(0,(crtcols-strlen(s))/2,7,s,0);
  1298.       s = "Pre-rotation X axis is screen top; Y axis is the left side";
  1299.       putstring(1,(crtcols-strlen(s))/2,7,s,0);
  1300.       s = "Pre-rotation Z axis is coming right at you out of the screen!";
  1301.       putstring(2,(crtcols-strlen(s))/2,7,s,0);
  1302.  
  1303.       prompts3d[0] = "X-axis rotation in degrees";
  1304.       prompts3d[1] = "Y-axis rotation in degrees";
  1305.       prompts3d[2] = "Z-axis rotation in degrees";
  1306.       prompts3d[3] = "X-axis scaling factor in pct";
  1307.       prompts3d[4] = "Y-axis scaling factor in pct";
  1308.    }
  1309.    values[0]   = XROT       ;
  1310.    values[1]   = YROT       ;
  1311.    values[2]   = ZROT       ;
  1312.    values[3]   = XSCALE    ;
  1313.    values[4]   = YSCALE    ;
  1314.    k = 5;
  1315.    prompts3d[k]= "Surface Roughness scaling factor in pct";
  1316.    values[k++] = ROUGH       ;
  1317.  
  1318.    prompts3d[k]= "'Water Level' (minimum color value)";
  1319.    values[k++] = WATERLINE ;
  1320.  
  1321.    prompts3d[k]= "Perspective distance [1 - 999, 0 for no persp]";
  1322.    values[k++] = ZVIEWER   ;
  1323.  
  1324.    prompts3d[k]= "X shift with perspective (positive = right)";
  1325.    values[k++] = XSHIFT    ;
  1326.  
  1327.    prompts3d[k]= "Y shift with perspective (positive = up   )";
  1328.    values[k++] = YSHIFT    ;
  1329.  
  1330.    prompts3d[k]= "Image non-perspective X adjust (positive = right)";
  1331.    values[k++] = xtrans    ;
  1332.  
  1333.    prompts3d[k]= "Image non-perspective Y adjust (positive = up)";
  1334.    values[k++] = ytrans    ;
  1335.  
  1336.    prompts3d[k]= "First transparent color";
  1337.    values[k++] = transparent[0];
  1338.  
  1339.    prompts3d[k]= "Last transparent color";
  1340.    values[k++] = transparent[1];
  1341.  
  1342.    prompts3d[k]= "Randomize Colors      (0 - 7, '0' disables)";
  1343.    values[k++] = RANDOMIZE;
  1344.  
  1345.    if (ILLUMINE)
  1346.    {
  1347.     prompts3d[k]= "Color/Mono Images With Light Source   (1 = Color)";
  1348.     values[k++] = full_color;
  1349.    }
  1350.  
  1351.    if (fullscreen_prompt(4,k,prompts3d,values) < 0)
  1352.       goto restart_1;
  1353.  
  1354.    k = 0;
  1355.    XROT       = values[k++];
  1356.    YROT       = values[k++];
  1357.    ZROT       = values[k++];
  1358.    XSCALE     = values[k++];
  1359.    YSCALE     = values[k++];
  1360.    ROUGH      = values[k++];
  1361.    WATERLINE  = values[k++];
  1362.    ZVIEWER    = values[k++];
  1363.    XSHIFT     = values[k++];
  1364.    YSHIFT     = values[k++];
  1365.    xtrans     = values[k++];
  1366.    ytrans     = values[k++];
  1367.    transparent[0] = values[k++];
  1368.    transparent[1] = values[k++];
  1369.    RANDOMIZE  = values[k++];
  1370.    if (RANDOMIZE >= 7) RANDOMIZE = 7;
  1371.    if (RANDOMIZE <= 0) RANDOMIZE = 0;
  1372.  
  1373.    if (ILLUMINE)
  1374.    {
  1375.     full_color = values[k++];
  1376.     if(get_light_params())
  1377.         goto restart_3;
  1378.    }
  1379.  
  1380. return(0);
  1381. }
  1382.  
  1383. /* --------------------------------------------------------------------- */
  1384. get_light_params()
  1385. {
  1386.    char *prompts3d[10];
  1387.    double values[10];
  1388.    struct fullscreenvalues uvalues[10];
  1389.    char *s;
  1390.    int k;
  1391.  
  1392.    /* defaults go here */
  1393.  
  1394.    setclear();
  1395.  
  1396.    s = "Light Source Parameters";
  1397.    putstring(0,(crtcols-strlen(s))/2,7,s,0);
  1398.  
  1399.    k = -1;
  1400.    prompts3d[++k]= "X value light vector";
  1401.    uvalues[k].type = 'd';
  1402.    uvalues[k].uval.dval = XLIGHT    ;
  1403.  
  1404.    prompts3d[++k]= "Y value light vector";
  1405.    uvalues[k].type = 'd';
  1406.    uvalues[k].uval.dval = YLIGHT    ;
  1407.  
  1408.    prompts3d[++k]= "Z value light vector";
  1409.    uvalues[k].type = 'd';
  1410.    uvalues[k].uval.dval = ZLIGHT    ;
  1411.  
  1412.    prompts3d[++k]= "Light Source Smoothing Factor";
  1413.    uvalues[k].type = 'd';
  1414.    uvalues[k].uval.dval = LIGHTAVG  ;
  1415.  
  1416.    prompts3d[++k]= "Ambient Light      (0 - 100, '0' = 'Black' shadows";
  1417.    uvalues[k].type = 'd';
  1418.    uvalues[k].uval.dval = Ambient;
  1419.  
  1420.    if (full_color)
  1421.    {
  1422.     prompts3d[++k]    = "Haze Factor        (0 - 100, '0' disables)";
  1423.     uvalues[k].type = 'd';
  1424.     uvalues[k].uval.dval= haze;
  1425.  
  1426.     prompts3d[++k]= "Full Color Light File Name (if not light001.tga)";
  1427.     uvalues[k].type = 's';
  1428.     strcpy(uvalues[k].uval.sval,light_name);
  1429.    }
  1430.  
  1431.    prompts3d[++k]= "";
  1432.  
  1433.    if (fullscreen_prompt2(3,k,prompts3d,uvalues) < 0)
  1434.       return(-1);
  1435.  
  1436.    k = 0;
  1437.       XLIGHT   = uvalues[k++].uval.dval;
  1438.       YLIGHT   = uvalues[k++].uval.dval;
  1439.       ZLIGHT   = uvalues[k++].uval.dval;
  1440.       LIGHTAVG = uvalues[k++].uval.dval;
  1441.       Ambient  = uvalues[k++].uval.dval;
  1442.       if (Ambient >= 100) Ambient = 100;
  1443.       if (Ambient <= 0) Ambient = 0;
  1444.    if (full_color)
  1445.    {
  1446.     haze  =  uvalues[k++].uval.dval;
  1447.     if (haze >= 100) haze = 100;
  1448.     if (haze <= 0) haze = 0;
  1449.     strcpy(light_name,uvalues[k].uval.sval);
  1450.    }
  1451.    return(0);
  1452. }
  1453.  
  1454. /* --------------------------------------------------------------------- */
  1455.  
  1456.  
  1457. check_mapfile()
  1458. {
  1459.     char temp[81];
  1460.     while ((FILLTYPE >= 5) || overlay3d || (mapset == 1) || glassestype)
  1461.     {
  1462.     setclear();
  1463.     movecursor(5,5);
  1464.     if (mapset && ((glassestype==0) || (glassestype==3)))
  1465.     {
  1466. static char far replmapmsg[]={"\
  1467. , has been previously selected.\n\
  1468. Press \"CR\" to continue using it.\n\
  1469. Enter \"*\" to use the palette from the image about to be loaded.\n  ==> "};
  1470.         printf("\n\nA replacement .MAP file, %s",MAP_name);
  1471.         helpmessage(replmapmsg);
  1472.         gets (temp1);
  1473.         if (temp1[0] == '\0') /* CR pressed */
  1474.         break;
  1475.         if (temp1[0] == '\x2A') /* "*" pressed */
  1476.         {
  1477.         mapset = 0;
  1478.         break;
  1479.         }
  1480.     }
  1481.     else if((glassestype==0) || (glassestype==3))
  1482.     {
  1483. static char far usemapmsg[]={"\
  1484. \n\nEnter name of .MAP file to use, or \n\
  1485. Press \"CR\" or enter \"*\" to use palette from the image about to be loaded.\n\
  1486.   ==> "};
  1487.         movecursor(5,5);
  1488.         helpmessage(usemapmsg);
  1489.         gets (temp1);
  1490.         if (temp1[0] == '\0' || temp1[0] == '\x2A')
  1491.         { /* CR or * pressed */
  1492.         mapset = 0;
  1493.         break;
  1494.         }
  1495.     }
  1496.     if(0 < glassestype && glassestype < 3)
  1497.        strcpy(temp1,funnyglasses_map_name);
  1498.     if (strchr(temp1,'.') == NULL) /* Did name have an extention? */
  1499.         strcat(temp1,".map"); /* No? Then add .map */
  1500.     findpath(temp1,temp); /* Find complete path name */
  1501.     dacfile = fopen(temp,"r"); /* Open it */
  1502.     if (dacfile == NULL)
  1503.     { /* Oops, somethings wrong */
  1504.         if(glassestype == 2)
  1505.         {
  1506.         mapset = 2; /* Need to generate glasses2.map */
  1507.         break;
  1508.         }
  1509.         else if (glassestype == 1)
  1510.         {
  1511.         mapset = 3; /* Need to generate glasses1.map */
  1512.         break; /* compute palette on the fly goes here */
  1513.         }
  1514.         buzzer(2);
  1515.         printf ("\nSorry, cannot open %s \n", temp1);
  1516.         printf (string004);
  1517.         getch();
  1518.         setclear();
  1519.         continue;
  1520.     }
  1521.     /* File has been opened OK */
  1522.     ValidateLuts(dacfile);    /* read the palette file to make sure its ok */
  1523.     fclose(dacfile); /* close it */
  1524.     mapset = 1;
  1525.     strcpy (MAP_name,temp);
  1526.     break; /* Done */
  1527.     }
  1528.     return(0);
  1529. }
  1530.  
  1531. get_funny_glasses_params()
  1532. {
  1533.    char *prompts3d[10];
  1534.    double values[10];
  1535.    struct fullscreenvalues uvalues[10];
  1536.    char *s;
  1537.    int k;
  1538.  
  1539.    /* defaults */
  1540.    if(ZVIEWER == 0)
  1541.       ZVIEWER = 150;
  1542.    if(eyeseparation == 0)
  1543.    {
  1544.       if(fractype==IFS3D || fractype==LLORENZ3D || fractype==FPLORENZ3D)
  1545.       {
  1546.      eyeseparation =  2;
  1547.      xadjust       = -2;
  1548.       }
  1549.       else
  1550.       {
  1551.      eyeseparation =  3;
  1552.      xadjust       =  0;
  1553.       }
  1554.    }
  1555.  
  1556.    if(glassestype == 1)
  1557.       strcpy(funnyglasses_map_name,"glasses1.map");
  1558.    else if(glassestype == 2)
  1559.       strcpy(funnyglasses_map_name,"glasses2.map");
  1560.  
  1561.    setclear();
  1562.  
  1563.    s = "Funny Glasses Parameters";
  1564.    putstring(0,(crtcols-strlen(s))/2,7,s,0);
  1565.  
  1566.    k = -1;
  1567.    prompts3d[++k]  = "Interocular distance (as % of screen)";
  1568.    uvalues[k].type = 'd';
  1569.    uvalues[k].uval.dval= eyeseparation;
  1570.  
  1571.    prompts3d[++k]= "Convergence adjust (positive = spread greater)";
  1572.    uvalues[k].type = 'd';
  1573.    uvalues[k].uval.dval = xadjust;
  1574.  
  1575.    prompts3d[++k]= "Left  red image crop (% of screen)";
  1576.    uvalues[k].type = 'd';
  1577.    uvalues[k].uval.dval = red_crop_left;
  1578.  
  1579.    prompts3d[++k]= "Right red image crop (% of screen)";
  1580.    uvalues[k].type = 'd';
  1581.    uvalues[k].uval.dval = red_crop_right;
  1582.  
  1583.    prompts3d[++k]= "Left  blue image crop (% of screen)";
  1584.    uvalues[k].type = 'd';
  1585.    uvalues[k].uval.dval = blue_crop_left;
  1586.  
  1587.    prompts3d[++k]= "Right blue image crop (% of screen)";
  1588.    uvalues[k].type = 'd';
  1589.    uvalues[k].uval.dval = blue_crop_right;
  1590.  
  1591.    prompts3d[++k]= "Red brightness factor (%)";
  1592.    uvalues[k].type = 'd';
  1593.    uvalues[k].uval.dval = red_bright;
  1594.  
  1595.    prompts3d[++k]= "Blue brightness factor (%)";
  1596.    uvalues[k].type = 'd';
  1597.    uvalues[k].uval.dval = blue_bright;
  1598.  
  1599.    if(glassestype != 3)
  1600.    {
  1601.       prompts3d[++k]= "Map File name (if not default)";
  1602.       uvalues[k].type = 's';
  1603.       strcpy(uvalues[k].uval.sval,funnyglasses_map_name);
  1604.    }
  1605.  
  1606.    prompts3d[++k]= "";
  1607.  
  1608.    if (fullscreen_prompt2(3,k,prompts3d,uvalues) < 0)
  1609.       return(-1);
  1610.  
  1611.    k = 0;
  1612.    eyeseparation   =  uvalues[k++].uval.dval;
  1613.    xadjust       =  uvalues[k++].uval.dval;
  1614.    red_crop_left   =  uvalues[k++].uval.dval;
  1615.    red_crop_right  =  uvalues[k++].uval.dval;
  1616.    blue_crop_left  =  uvalues[k++].uval.dval;
  1617.    blue_crop_right =  uvalues[k++].uval.dval;
  1618.    red_bright       =  uvalues[k++].uval.dval;
  1619.    blue_bright       =  uvalues[k++].uval.dval;
  1620.  
  1621.    if(glassestype != 3)
  1622.       strcpy(funnyglasses_map_name,uvalues[k].uval.sval);
  1623.    return(0);
  1624. }
  1625.  
  1626. /* --------------------------------------------------------------------- */
  1627.  
  1628. get_ifs_params()        /* prompt for IFS params */
  1629. {
  1630. char *s;
  1631. int numcols;              /* number of columns */
  1632. int startrow, startcol;       /* upper left corner of list */
  1633. char *choices[4], choicetext[4][50];
  1634. char *filename;
  1635. float far *initarray;
  1636. static char ifstype = '2';
  1637. int totrows, totcols;
  1638. int i, j, numlines;
  1639. FILE *tempfile;
  1640.  
  1641. for (i = 0; i < 4; i++)
  1642.     choices[i] = choicetext[i];
  1643.  
  1644. setfortext();            /* switch to text mode */
  1645.  
  1646. memcpy(olddacbox,dacbox,256*3);        /* save the DAC */
  1647. setvideomode(3,0,0,0);               /* clear the screen entirely */
  1648. memcpy(dacbox,olddacbox,256*3);        /* restore the DAC */
  1649.  
  1650.  
  1651. ifsgetfile();            /* read in any "IFS=" file */
  1652.  
  1653. ifs3dgetfile();         /* read in any "IFS3D=" file */
  1654.  
  1655. filename = ifsfilename;
  1656. initarray = &initifs[0][0];
  1657. totrows = NUMIFS;
  1658. totcols = IFSPARM;
  1659.  
  1660. /* assume if an IFS type is already selected, user wants to edit that type */
  1661. ifstype = 0;
  1662. if(fractype == IFS)
  1663.    ifstype = '2';
  1664. else if (fractype == IFS3D)
  1665.    ifstype = '3';
  1666. else if (calc_status >= 0) {   /* there's a fractal image active */
  1667.    ifstype = 't';
  1668.    get_ifs3d_params();
  1669.    return(0);
  1670.    }
  1671.    strcpy(choices[0],"2D IFS Codes");
  1672.    strcpy(choices[1],"3D IFS Codes");
  1673.    strcpy(choices[2],"3D Transform Parameters");
  1674.  
  1675.    /* set up details of how type list is displayed on the screen */
  1676.    numcols  =  1;          /* number of columns */
  1677.    startrow =  5;          /* upper left corner of list */
  1678.    startcol = 30;          /* upper left corner of list */
  1679.    fullscreen_setup(); /* just to get value of crtcols */
  1680.    setclear();
  1681.  
  1682.    s = "Edit Options";
  1683.    putstring(0,(crtcols-strlen(s))/2,7,s,0);
  1684.    if(ifstype == '2')
  1685.       i = 0;
  1686.    else if(ifstype == '3')
  1687.       i = 1;
  1688.   else
  1689.       i = 2;
  1690.     i = fullscreen_choice(3, choices,numcols,startrow,startcol,i);
  1691.     switch(i)
  1692.     {
  1693.     case 0:
  1694.        ifstype = '2';
  1695.        break;
  1696.     case 1:
  1697.        ifstype = '3';
  1698.        break;
  1699.     case 2:
  1700.        printf("\n\n");
  1701.        get_ifs3d_params();
  1702.        return(0);
  1703.        break;
  1704.      default:
  1705.        return(0);
  1706.        break;
  1707.     }
  1708. if (ifstype == '3') {
  1709.    filename = ifs3dfilename;
  1710.    initarray = &initifs3d[0][0];
  1711.    totrows = NUMIFS;
  1712.    totcols = IFS3DPARM;
  1713.    }
  1714.  
  1715. for ( ;; ) {
  1716.  
  1717.     for (numlines = 0; numlines < totrows; numlines++)      /* find the first zero entry */
  1718.     if (initarray[(numlines * totcols) + totcols - 1] <= 0.0001) break;
  1719.  
  1720.     memcpy(olddacbox,dacbox,256*3);       /* save the DAC */
  1721.     setvideomode(3,0,0,0);           /* clear the screen entirely */
  1722.     memcpy(dacbox,olddacbox,256*3);       /* restore the DAC */
  1723.  
  1724. {
  1725. static char far ifsparmmsg1[]={"\
  1726.  Your current IFS Parameters are: \n\n\
  1727. #   a      b    c     d     e      f"};
  1728. static char far ifsparmmsg2[]={"\
  1729.      g       h     i     j     k       l"};
  1730.     helpmessage(ifsparmmsg1);
  1731.     if (ifstype == '3')
  1732.     helpmessage(ifsparmmsg2);
  1733.     printf("    prob \n\n");
  1734. }
  1735.  
  1736.     for (i = 0; i < numlines; i++) {
  1737.     printf("%1d", i+1);
  1738.     for (j = 0; j < totcols; j++)
  1739.         printf("%6.2f", (float )initarray[(i*totcols)+j]);
  1740.     printf("\n");
  1741.     }
  1742.  
  1743. {
  1744. static char far ifseditmsg1[]={"\
  1745. \n\n Enter the number of the line you want to edit\n\
  1746.   (or RESTORE to start from another (.IFS) file, or SAVE to\n"};
  1747. static char far ifseditmsg2[]={"\
  1748.    save your edits in an (.IFS) file, or TRANSFORM to alter\n\
  1749.    3D transformation values, or <ENTER> to end) ==> "};
  1750. static char far ifseditmsg3[]={"\
  1751.    save your edits in an (.IFS) file, or <ENTER> to end) ==> "};
  1752.     helpmessage(ifseditmsg1);
  1753.     if(ifstype == '3')
  1754.        helpmessage(ifseditmsg2);
  1755.     else
  1756.        helpmessage(ifseditmsg3);
  1757. }
  1758.     gets(temp1);
  1759.     if (ifstype == '3' && (temp1[0] == 't' || temp1[0] == 'T')) {
  1760.        get_ifs3d_params();
  1761.        continue;
  1762.        }
  1763.     if (temp1[0] == 's' || temp1[0] == 'S') {
  1764.        printf("\n\n enter the name of your new .IFS file ==> ");
  1765.        gets(filename);
  1766.        if (strchr(filename,'.') == NULL)
  1767.       strcat(filename,".ifs");
  1768.        if ((tempfile=fopen(filename,"w")) != NULL) {
  1769.       for (i = 0; i < numlines; i++) {
  1770.          for (j = 0; j < totcols; j++)
  1771.         fprintf(tempfile, "%6.2f", (float)initarray[(i*totcols)+j]);
  1772.          fprintf(tempfile, "\n");
  1773.          }
  1774.       fclose(tempfile);
  1775.       }
  1776.        return(0);
  1777.        }
  1778.     if (temp1[0] == 'r' || temp1[0] == 'R') {
  1779.        printf("\n\n enter the name of your new .IFS file ==> ");
  1780.        gets(filename);
  1781.        if (strchr(filename,'.') == NULL)
  1782.       strcat(filename,".ifs");
  1783.        if (ifstype == '3')
  1784.       ifs3dgetfile();
  1785.        else
  1786.       ifsgetfile();
  1787.        continue;
  1788.        }
  1789.     i = atoi(temp1) - 1;
  1790.     if (temp1[0] == 0 || i < 0 || i > numlines) return(0);
  1791.  
  1792.     for (j = 0; j < totcols; j++) {
  1793.     printf(" Parameter %2d (if not %6.2f) ", j, (float)initarray[(i*totcols)+j]);
  1794.     gets(temp1);
  1795.     if (temp1[0] != 0)
  1796.         initarray[(i*totcols)+j] = atof(temp1);
  1797.     }
  1798.     }
  1799. }
  1800.  
  1801. /* --------------------------------------------------------------------- */
  1802. /*
  1803.     get_toggles() is called from FRACTINT.C whenever the 'x' key
  1804.     is pressed.  This routine prompts for several options,
  1805.     sets the appropriate variables, and returns the following code
  1806.     to the calling routine:
  1807.  
  1808.     -1  routine was ESCAPEd - no need to re-generate the image.
  1809.      0  minor variable changed (such as "warn=").  No need to
  1810.         re-generate the image.
  1811.     1   major variable changed (such as "inside=").  Re-generate
  1812.         the image.
  1813.     2   Floating-point toggle changed.  FRACTINT.C takes special
  1814.         actions in this instance, as the algorithm itself changes.
  1815.  
  1816.     Finally, remember to insert variables in the list *and* check
  1817.     for them in the same order!!!
  1818. */
  1819.  
  1820. get_toggles()
  1821. {
  1822.    int numcols;         /* number of columns */
  1823.    int startrow;        /* upper left corner of list */
  1824.    int startcol;        /* upper left corner of list */
  1825.    char *choices[20];
  1826.    char c;
  1827.    int numprompts;
  1828.    char *s;
  1829.    int oldhelpmode;
  1830.  
  1831.    double values[25], oldvalues[25];
  1832.  
  1833.    struct fullscreenvalues uvalues[25];
  1834.    int i, j, k, ipasses;
  1835.  
  1836.    /* fill up the choices (and previous values) arrays */
  1837.    k = -1;
  1838.  
  1839.    k++;
  1840.    choices[k] =  "Floating Point Algorithm";
  1841.    uvalues[k].type = 's';
  1842.    oldvalues[k] = floatflag;
  1843.    if (floatflag)
  1844.       strcpy(uvalues[k].uval.sval,"yes");
  1845.    else
  1846.       strcpy(uvalues[k].uval.sval,"no");
  1847.  
  1848.    k++;
  1849.    choices[k] =  "Passes (1, 2, g[uessing], or b[oundary trace])";
  1850.    uvalues[k].type = 's';
  1851.    oldvalues[k] = boundarytraceflag*100 + numpasses + solidguessing;
  1852.    /* passes klooge */
  1853.    strcpy(uvalues[k].uval.sval,"1");
  1854.    if (boundarytraceflag == 1)
  1855.       uvalues[k].uval.sval[0] = 'b';
  1856.    else if (solidguessing == 1)
  1857.      uvalues[k].uval.sval[0] = 'g';
  1858.    else
  1859.      uvalues[k].uval.sval[0] = '1' + numpasses;
  1860.  
  1861.    k++;
  1862.    choices[k] = "Biomorph Color (-1 means OFF)";
  1863.    uvalues[k].type = 'd';
  1864.    uvalues[k].uval.dval = oldvalues[k] = biomorph;
  1865.  
  1866.    k++;
  1867.    choices[k] = "Decomp Option (2,4,8,..,256, 0=OFF)";
  1868.    uvalues[k].type = 'd';
  1869.    oldvalues[k] = decomp[0];
  1870.    uvalues[k].uval.dval = oldvalues[k];
  1871.  
  1872.    k++;
  1873.    choices[k] = "Maximum Iterations (10 to 32000)";
  1874.    uvalues[k].type = 'd';
  1875.    oldvalues[k] = maxit;
  1876.    uvalues[k].uval.dval = oldvalues[k];
  1877.  
  1878.    k++;
  1879.    choices[k] = "Inside Color (nnnn, maxiter, bof60, bof61)";
  1880.    uvalues[k].type = 's';
  1881.    if(inside == -60)
  1882.       strcpy(uvalues[k].uval.sval,"bof60");
  1883.    else if(inside == -61)
  1884.       strcpy(uvalues[k].uval.sval,"bof61");
  1885.    else if(inside == -1)
  1886.       strcpy(uvalues[k].uval.sval,"maxiter");
  1887.    else
  1888.       sprintf(uvalues[k].uval.sval,"%d",inside);
  1889.    oldvalues[k] = inside;
  1890.  
  1891.    k++;
  1892.    choices[k] = "Outside Color (-1 means none)";
  1893.    uvalues[k].type = 'd';
  1894.    oldvalues[k] = outside;
  1895.    uvalues[k].uval.dval = oldvalues[k];
  1896.  
  1897.    k++;
  1898.    choices[k] = "Look for finite attractor";
  1899.    uvalues[k].type = 's';
  1900.    oldvalues[k] = finattract;
  1901.    if (finattract)
  1902.       strcpy(uvalues[k].uval.sval,"yes");
  1903.    else
  1904.       strcpy(uvalues[k].uval.sval,"no");
  1905.  
  1906.    k++;
  1907.    choices[k] = "Logarithmic Palettes";
  1908.    uvalues[k].type = 's';
  1909.    oldvalues[k] = LogFlag;
  1910.    if (LogFlag == 1)
  1911.       strcpy(uvalues[k].uval.sval,"yes");
  1912.    else if (LogFlag == 2)
  1913.       strcpy(uvalues[k].uval.sval,"old");
  1914.    else
  1915.       strcpy(uvalues[k].uval.sval,"no");
  1916.  
  1917.    k++;
  1918.    choices[k] = "File Overwrite ('warn=')";
  1919.    uvalues[k].type = 's';
  1920.    oldvalues[k] = warn;
  1921.    if (warn)
  1922.       strcpy(uvalues[k].uval.sval,"yes");
  1923.    else
  1924.       strcpy(uvalues[k].uval.sval,"no");
  1925.  
  1926.    k++;
  1927.    choices[k] = "Savename (.GIF implied)";
  1928.    uvalues[k].type = 's';
  1929.    oldvalues[k] = 0;
  1930.    strcpy(uvalues[k].uval.sval,savename);
  1931.  
  1932.    k++;
  1933.    choices[k] = "Sound (no, yes, x, y, z)";
  1934.    uvalues[k].type = 's';
  1935.    oldvalues[k] = soundflag;
  1936.    strcpy(uvalues[k].uval.sval,"no");
  1937.    if (soundflag == -1)
  1938.       strcpy(uvalues[k].uval.sval,"yes");
  1939.    if (soundflag == 1)
  1940.       strcpy(uvalues[k].uval.sval,"x");
  1941.    if (soundflag == 2)
  1942.       strcpy(uvalues[k].uval.sval,"y");
  1943.    if (soundflag == 3)
  1944.       strcpy(uvalues[k].uval.sval,"z");
  1945. /*
  1946.    k++;
  1947.    choices[k] = "Bailout value (0 means use default)";
  1948.    uvalues[k].type = 'd';
  1949.    uvalues[k].uval.dval = oldvalues[k] = bailout;
  1950. */
  1951.    k++;
  1952.    choices[k] = "Distance Estimator Method (0 means off):";
  1953.    uvalues[k].type = 'd';
  1954.    oldvalues[k] = distest;
  1955.    uvalues[k].uval.dval = oldvalues[k];
  1956.  
  1957.    k++;
  1958.    choices[k] = "Potential param #1 (max color)";
  1959.    uvalues[k].type = 'd';
  1960.    uvalues[k].uval.dval = oldvalues[k] = potparam[0];
  1961.  
  1962.    k++;
  1963.    choices[k] = "Potential param #2 (slope)";
  1964.    uvalues[k].type = 'd';
  1965.    uvalues[k].uval.dval = oldvalues[k] = potparam[1];
  1966.  
  1967.    k++;
  1968.    choices[k] = "Potential param #3 (bailout)";
  1969.    uvalues[k].type = 'd';
  1970.    uvalues[k].uval.dval = oldvalues[k] = potparam[2];
  1971.  
  1972.    k++;
  1973.    choices[k] = "Potential savefile name";
  1974.    uvalues[k].type = 's';
  1975.    oldvalues[k] = 0;
  1976.    strcpy(uvalues[k].uval.sval,potfile);
  1977.  
  1978.    fullscreen_setup();        /* set up for full-screen prompting */
  1979.  
  1980.    putstring(0,10,7,"The following options and doodads are in effect.",0);
  1981.    putstring(1,10,7,"Note that not all combinations make sense.",0);
  1982.  
  1983.    oldhelpmode = helpmode;     /* this prevents HELP from activating */
  1984.    helpmode = HELPAUTHORS;
  1985.    i = fullscreen_prompt2(4,k+1,choices,uvalues);
  1986.    helpmode = oldhelpmode;     /* re-enable HELP */
  1987.    if (i < 0)
  1988.       return(-1);
  1989.  
  1990.    /* now check out the results (*hopefully* in the same order <grin>) */
  1991.    k = -1;
  1992.    j = 0;   /* return code */
  1993.  
  1994.    if (uvalues[++k].uval.sval[0] == 'y' || uvalues[k].uval.sval[0] == 'Y')
  1995.       floatflag = 1;
  1996.    else
  1997.       floatflag = 0;
  1998.    if (floatflag != oldvalues[k]) j = 2;
  1999.  
  2000.    /* passes= klooge */
  2001.    if (uvalues[++k].uval.sval[0] == 'b' || uvalues[k].uval.sval[0] == 'B') {
  2002.       boundarytraceflag = 1;
  2003.       }
  2004.    else {
  2005.       boundarytraceflag = 0;
  2006.    }
  2007.    if (uvalues[k].uval.sval[0] == '1' || uvalues[k].uval.sval[0] == '2') {
  2008.       numpasses = uvalues[k].uval.sval[0] - '1';
  2009.       solidguessing = 0;
  2010.       }
  2011.    if (uvalues[k].uval.sval[0] == 'g' || uvalues[k].uval.sval[0] == 'G') {
  2012.       numpasses = 1;
  2013.       solidguessing = 1;
  2014.       }
  2015.    ipasses = boundarytraceflag*100 + numpasses + solidguessing;
  2016.    if (ipasses != oldvalues[k] && j < 1) j = 1;
  2017.  
  2018.    biomorph = uvalues[++k].uval.dval;
  2019.    if (biomorph != oldvalues[k] && j < 1) j = 1;
  2020.  
  2021.    decomp[0] = uvalues[++k].uval.dval;
  2022.    if (decomp[0] != oldvalues[k] && j < 1) j = 1;
  2023.  
  2024.    maxit = uvalues[++k].uval.dval;
  2025.    if (maxit != oldvalues[k] && j < 1) j = 1;
  2026.  
  2027.    if(strncmp(strlwr(uvalues[++k].uval.sval),"bof60",5)==0)
  2028.       inside = -60;
  2029.    else if(strncmp(strlwr(uvalues[k].uval.sval),"bof61",5)==0)
  2030.       inside = -61;
  2031.    else if(strncmp(strlwr(uvalues[k].uval.sval),"maxiter",5)==0)
  2032.       inside = -1;
  2033.    else
  2034.       inside = atoi(uvalues[k].uval.sval);
  2035.    if (inside != oldvalues[k] && j < 1) j = 1;
  2036.  
  2037.    outside = uvalues[++k].uval.dval;
  2038.    if (outside != oldvalues[k] && j < 1) j = 1;
  2039.  
  2040.    if (uvalues[++k].uval.sval[0] == 'y' || uvalues[k].uval.sval[0] == 'Y')
  2041.       finattract = 1;
  2042.    else
  2043.       finattract = 0;
  2044.    if (finattract != oldvalues[k]) j = 2;
  2045.  
  2046.    if (uvalues[++k].uval.sval[0] == 'y' || uvalues[k].uval.sval[0] == 'Y')
  2047.       LogFlag = 1;
  2048.    else if (uvalues[k].uval.sval[0] == 'o' || uvalues[k].uval.sval[0] == 'O')
  2049.       LogFlag = 2;
  2050.    else
  2051.       LogFlag = 0;
  2052.    if (LogFlag != oldvalues[k] && j < 1) j = 1;
  2053.  
  2054.    if (uvalues[++k].uval.sval[0] == 'y' || uvalues[k].uval.sval[0] == 'Y')
  2055.       warn = 1;
  2056.    else
  2057.       warn = 0;
  2058.  
  2059.    strcpy(savename,uvalues[++k].uval.sval);
  2060.  
  2061.    if (strnicmp(uvalues[++k].uval.sval,"yes",2) == 0) {
  2062.       soundflag = -1;
  2063.       uvalues[k].uval.sval[0] = 'q';
  2064.       }
  2065.    else
  2066.       soundflag = 0;
  2067.    if (uvalues[k].uval.sval[0] == 'x' || uvalues[k].uval.sval[0] == 'X')
  2068.       soundflag = 1;
  2069.    if (uvalues[k].uval.sval[0] == 'y' || uvalues[k].uval.sval[0] == 'Y')
  2070.       soundflag = 2;
  2071.    if (uvalues[k].uval.sval[0] == 'z' || uvalues[k].uval.sval[0] == 'Z')
  2072.       soundflag = 3;
  2073.    if (soundflag != oldvalues[k] && (soundflag > 1 || oldvalues[k] > 1) &&
  2074.       j < 1) j = 1;
  2075. /*
  2076.    bailout = uvalues[++k].uval.dval;
  2077.    if (bailout != 0 && (bailout < 4 || bailout > 32000))
  2078.       bailout = oldvalues[k];
  2079.    if (bailout != oldvalues[k] && j < 1) j = 1;
  2080. */
  2081.    distest = uvalues[++k].uval.dval;
  2082.    if (distest != oldvalues[k]) j = 2;
  2083.  
  2084.    potparam[0] = uvalues[++k].uval.dval;
  2085.    if (potparam[0] != oldvalues[k] && j < 1) j = 1;
  2086.  
  2087.    potparam[1] = uvalues[++k].uval.dval;
  2088.    if (potparam[0] != 0.0 && potparam[1] != oldvalues[k] && j < 1) j = 1;
  2089.  
  2090.    potparam[2] = uvalues[++k].uval.dval;
  2091.    if (potparam[0] != 0.0 && potparam[2] != oldvalues[k] && j < 1) j = 1;
  2092.  
  2093.    strcpy(potfile,uvalues[++k].uval.sval);
  2094.    /* fullscreenprompt2 inserts blanks */
  2095.    if(potfile[0] == 32)
  2096.       potfile[0] = 0;
  2097.  
  2098.    return(j);
  2099. }
  2100.  
  2101. /*  **** the routines below this point are *not* prompting routines ***  */
  2102.  
  2103.  
  2104. /* --------------------------------------------------------------------- */
  2105.  
  2106. get_obsolete()            /* notify user of obsolete switches */
  2107. {
  2108. static char far obsmsg[]={"\
  2109. \n\n\nWell, the key you pressed *used* to be a valid command key,\n\
  2110. but it has since become obsolete.  Please use the following keys\n\
  2111. instead.\n\n\
  2112.   F1      for help\n\n\
  2113.   x or X  to set a number of options\n\
  2114. \n\n"};
  2115. helpmessage(obsmsg);
  2116. printf(string004);
  2117. getakey();
  2118. }
  2119.  
  2120. /* --------------------------------------------------------------------- */
  2121.  
  2122. tab_display()            /* display the status of the current image */
  2123. {
  2124. int numfn;
  2125. extern double xxmin, xxmax, xx3rd, yymin, yymax, yy3rd;
  2126. extern long calctime, timer_start;
  2127. int i;
  2128. double Xctr, Yctr, Magnification;
  2129.  
  2130. if (calc_status < 0)        /* no active fractal image */
  2131.     return (0);        /* (no TAB on the credits screen) */
  2132.  
  2133. if (calc_status == 1)        /* next assumes CLK_TCK is 10^n, n>=2 */
  2134.     calctime += (clock() - timer_start) / (CLK_TCK/100);
  2135.  
  2136. setfortext();
  2137.  
  2138. printf("\n\nCurrent Fractal Type is: %-15s  ",
  2139.     fractalspecific[fractype].name[0] == '*' ?
  2140.     &fractalspecific[fractype].name[1] :
  2141.     fractalspecific[fractype].name
  2142.     );
  2143.  
  2144. switch (calc_status) {
  2145. case 0: printf("(parms chgd since generated)\n");
  2146.     break;
  2147. case 1: printf("(still being generated)\n");
  2148.     break;
  2149. case 2: printf("(interrupted, resumable)\n");
  2150.     break;
  2151. case 3: printf("(interrupted, non-resumable)\n");
  2152.     break;
  2153. case 4: printf("(image completed)\n");
  2154. }
  2155.  
  2156. showtrig(stdout);
  2157. if (fractype == FORMULA || fractype == FFORMULA)
  2158.     printf("Formula name: %s\n",FormName);
  2159.  
  2160. if (calc_status == 1 || calc_status == 2)
  2161. {
  2162.     if (fractalspecific[fractype].flags&INFCALC)
  2163.         printf("Note: this type runs forever.\n");
  2164.     if (fractalspecific[fractype].flags&NORESUME || potfile[0] != 0)
  2165.     {
  2166.         printf("Note: can't resume this type after interrupts other than <tab> and <F1>\n");
  2167.         if (fractalspecific[fractype].flags&NORESUME == 0)
  2168.         printf("      (Due to generation of potential file.)\n");
  2169.     }
  2170. }
  2171.  
  2172. if (helpmode == HELPCYCLING)
  2173.     printf("%s  %s\n",
  2174.         "                                        ",
  2175.         "(You are in color-cycling mode)");
  2176.  
  2177. printf("\nCalculation time:%3ld:%02ld:%02ld.%02ld", calctime/360000,
  2178.     (calctime%360000)/6000, (calctime%6000)/100, calctime%100);
  2179. if (floatflag)
  2180.     printf("             Floating-point flag is activated");
  2181. printf("\n\n");
  2182.  
  2183. for(i=0;i<4;i++) {
  2184.     printf("   Param%1d = %12.9f ",i+1,param[i]);
  2185.     if ((i & 1) != 0)
  2186.         printf("\n");
  2187.     }
  2188.  
  2189. printf("\nCurrent Corners:        X                     Y\n");
  2190. printf(" top-left      %20.16f  %20.16f\n",xxmin,yymax);
  2191. printf(" bottom-right  %20.16f  %20.16f\n",xxmax,yymin);
  2192. adjust_corner(); /* make bottom left exact if very near exact */
  2193. if (cvtcentermag(&Xctr, &Yctr, &Magnification))
  2194.    printf("\nCenter: %20.16f  %20.16f Mag: %20.16f\n",Xctr,Yctr,Magnification);
  2195. else if (xxmin != xx3rd || yymin != yy3rd)
  2196.    printf(" bottom-left   %20.16f  %20.16f\n",xx3rd,yy3rd);
  2197.  
  2198. printf("\nCurrent Iteration Maximum = %d  Effective Bailout = %f\n",maxit,rqlim);
  2199.  
  2200. if (fractype == PLASMA)
  2201.     printf("\nCurrent 'rseed=' value is %d\n",rseed);
  2202.  
  2203. if(invert) {
  2204.     extern double f_radius,f_xcenter,f_ycenter;
  2205.     printf("\nCurrent Inversion parameters are: \n");
  2206.     printf("   radius = %12.9f \n",f_radius);
  2207.     printf("  xcenter = %12.9f \n",f_xcenter);
  2208.     printf("  ycenter = %12.9f \n",f_ycenter);
  2209.     }
  2210.  
  2211. printf("\n%s",string004);
  2212. getakey();
  2213. setforgraphics();
  2214.  
  2215. timer_start = clock(); /* tab display was "time out" */
  2216.  
  2217. return(0);
  2218. }
  2219.  
  2220. showtrig(FILE *batch) /* display active trig functions */
  2221. {
  2222.    int numfn;
  2223.    if(numfn=get_trig_num(fractalspecific[initfractype].flags))
  2224.    {
  2225.       int i;
  2226.       fprintf(batch, " function=%s",trigfn[trigndx[0]].name);
  2227.       i = 0;
  2228.       while(++i < numfn)
  2229.      fprintf(batch, "/%s",trigfn[trigndx[i]].name);
  2230.       if(batch == stdout)
  2231.      fprintf(batch, "\n");
  2232.    }
  2233.    return(0);
  2234. }
  2235.  
  2236. /* --------------------------------------------------------------------- */
  2237.  
  2238. ifsgetfile()        /* read in IFS parameters */
  2239. {
  2240.    FILE  *ifsfile;        /* IFS code file pointer */
  2241.    float localifs[IFSPARM];
  2242.    int i, j;
  2243.  
  2244.    /* read in IFS codes from file */
  2245.    if (ifsfilename[0] != 0) {
  2246.       findpath(ifsfilename, temp1);
  2247.       if ( (ifsfile = fopen( temp1,"r" )) != NULL ) {
  2248.      i = -1;
  2249.      while (fgets(temp1, 155, ifsfile) != NULL) {
  2250.         if (++i >= NUMIFS) break;
  2251.         sscanf(temp1," %f %f %f %f %f %f %f",
  2252.            &localifs[0], &localifs[1], &localifs[2], &localifs[3],
  2253.            &localifs[4], &localifs[5], &localifs[6]  );
  2254.         for (j = 0; j < IFSPARM; j++) {
  2255.            initifs[i][j]   = localifs[j];
  2256.            initifs[i+1][j] = 0.0;
  2257.            }
  2258.         }
  2259.      fclose(ifsfile);
  2260.      }
  2261.       ifsfilename[0] = 0;
  2262.       }
  2263. }
  2264.  
  2265. /* --------------------------------------------------------------------- */
  2266.  
  2267. ifs3dgetfile()        /* read in 3D IFS parameters */
  2268. {
  2269.    FILE  *ifsfile;        /* IFS code file pointer */
  2270.    float localifs[IFS3DPARM];
  2271.    int i, j;
  2272.  
  2273.    /* read in IFS codes from file */
  2274.    if (ifs3dfilename[0] != 0) {
  2275.       findpath(ifs3dfilename, temp1);
  2276.       if ( (ifsfile = fopen( temp1,"r" )) != NULL ) {
  2277.      i = -1;
  2278.      while (fgets(temp1, 155, ifsfile) != NULL) {
  2279.         if (++i >= NUMIFS) break;
  2280.         sscanf(temp1," %f %f %f %f %f %f %f %f %f %f %f %f %f",
  2281.            &localifs[ 0], &localifs[ 1], &localifs[ 2],
  2282.            &localifs[ 3], &localifs[ 4], &localifs[ 5],
  2283.            &localifs[ 6], &localifs[ 7], &localifs[ 8],
  2284.            &localifs[ 9], &localifs[10], &localifs[11],
  2285.            &localifs[12]
  2286.            );
  2287.         for (j = 0; j < IFS3DPARM; j++) {
  2288.            initifs3d[i][j]     = localifs[j];
  2289.            initifs3d[i+1][j] = 0.0;
  2290.            }
  2291.         }
  2292.      fclose(ifsfile);
  2293.      }
  2294.       ifs3dfilename[0] = 0;
  2295.       }
  2296. }
  2297.  
  2298.  
  2299. /* --------------------------------------------------------------------- */
  2300.  
  2301. static int Distribution = 30, Offset = 0, Slope = 25;
  2302. static long con, distfactor;
  2303.  
  2304. static char *starfield_prompts[4] = {
  2305.     "Star Density in Pixels per Star",
  2306.     "Percent Clumpiness",
  2307.     "Ratio of Dim stars to Bright",
  2308.     ""
  2309.     };
  2310. static double starfield_values[4] = {
  2311.     30.0,100.0,25.0,0.0
  2312.     };
  2313.  
  2314. int get_starfield_params(void) {
  2315.    static char StarMap[] = "altern.map";
  2316.    int i, c;
  2317.    double values[3];
  2318.    extern int loadPalette;
  2319.  
  2320.    if(colors < 255) {
  2321.       buzzer(2);
  2322.       return(-1);
  2323.    }
  2324.    setfortext();        /* switch to text mode */
  2325.    fullscreen_setup();        /* set up for full-screen prompting */
  2326.  
  2327.    for (i = 0; i < 3; i++)
  2328.       values[i] = starfield_values[i];
  2329.    printf("\n\nPlease enter your Starfield Parameters:\n");
  2330.    if (fullscreen_prompt(10,3,starfield_prompts,values) < 0) {
  2331.       setforgraphics();     /* back to graphics */
  2332.       return(-1);
  2333.       }
  2334.    setforgraphics();        /* back to graphics */
  2335.  
  2336.    for (i = 0; i < 3; i++)
  2337.       starfield_values[i] = values[i];
  2338.  
  2339.    if (starfield_values[0] <   1.0) starfield_values[0] =   1.0;
  2340.    if (starfield_values[0] > 100.0) starfield_values[0] = 100.0;
  2341.    if (starfield_values[1] <   1.0) starfield_values[1] =   1.0;
  2342.    if (starfield_values[1] > 100.0) starfield_values[1] = 100.0;
  2343.    if (starfield_values[2] <   1.0) starfield_values[2] =   1.0;
  2344.    if (starfield_values[2] > 100.0) starfield_values[2] = 100.0;
  2345.  
  2346.    Distribution = (int)(starfield_values[0]);
  2347.    con    = (long)(((starfield_values[1]) / 100.0) * (1L << 16));
  2348.    Slope = (int)(starfield_values[2]);
  2349.  
  2350.    SetColorPaletteName(StarMap);
  2351.    if(!loadPalette)
  2352.       return(-1);
  2353.    spindac(0,1);         /* load it, but don't spin */
  2354.  
  2355.    for(row = 0; row < ydots; row++) {
  2356.       for(col = 0; col < xdots; col++) {
  2357.      if(check_key()) {
  2358.         buzzer(1);
  2359.         return(-1);
  2360.         }
  2361.      c = getcolor(col, row);
  2362.      putcolor(col, row, GausianNumber(c, colors));
  2363.       }
  2364.    }
  2365.    buzzer(0);
  2366.    return(0);
  2367. }
  2368.  
  2369. int GausianNumber(int Probability, int Range) {
  2370.    int n, r;
  2371.    long Accum = 0, p;
  2372.  
  2373.    p = divide((long)Probability << 16, (long)Range << 16, 16);
  2374.    p = multiply(p, con, 16);
  2375.    p = multiply((long)Distribution << 16, p, 16);
  2376.    if(!(rand() % (Distribution - (int)(p >> 16) + 1))) {
  2377.       for(n = 0; n < Slope; n++)
  2378.      Accum += rand();
  2379.       Accum /= Slope;
  2380.       r = (int)(multiply((long)Range << 15, Accum, 15) >> 14);
  2381.       r = r - Range;
  2382.       if(r < 0)
  2383.      r = -r;
  2384.       return(Range - r + Offset);
  2385.    }
  2386.    return(Offset);
  2387. }
  2388.  
  2389.  
  2390. /* --------------------------------------------------------------------- */
  2391.  
  2392. extern char far argerrormessage[];    /* display argument error and die */
  2393.  
  2394. argerror(badarg)            /* oops.   couldn't decode this */
  2395. char *badarg;
  2396. {
  2397.  
  2398. setvideomode(3,0,0,0);
  2399. buzzer(2);
  2400. printf("\nOops.   I couldn't understand the argument '%s'\n\n",badarg);
  2401. helpmessage(argerrormessage);
  2402. exit(1);
  2403.  
  2404. }
  2405.  
  2406. /* --------------------------------------------------------------------- */
  2407.  
  2408. extern char far goodbyemessage[];
  2409.  
  2410. goodbye()            /* we done.  Bail out */
  2411. {
  2412. union REGS r;
  2413. setvideomode(3,0,0,0);
  2414. r.h.al = 3;
  2415. r.h.ah = 0;
  2416. int86(0x10, &r, &r);
  2417. helpmessage(goodbyemessage);
  2418. exit(0);
  2419. }
  2420.  
  2421. get_trig_num(int i) /* decode number of trig functions */
  2422. {
  2423.   i = i >> 6;
  2424.   i &= 7;
  2425.   return(i);
  2426. }
  2427.